// ignore_for_file: non_constant_identifier_names, avoid_print

import 'dart:convert';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/model/group_custom_data_model.dart';
import 'package:tencent_cloud_chat_uikit/czm_custom_widget/czm_widget_bridge.dart';
import 'package:tencent_cloud_chat_uikit/czm_method/czm_method_bridge.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart';
import 'package:tencent_im_base/tencent_im_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';

import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart';

import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart';

class TIMUIKitMessageTooltip extends StatefulWidget {
  /// tool tips panel configuration, long press message will show tool tips panel
  final ToolTipsConfig? toolTipsConfig;

  /// current message
  final V2TimMessage message;

  /// allow notifi user when send reply message
  final bool allowAtUserWhenReply;

  /// the callback for long press event, except myself avatar
  final Function({String? userId, String? nameCard, String? nickName})? onLongPressForOthersHeadPortrait;

  final bool isUseMessageReaction;

  /// direction
  final SelectEmojiPanelPosition selectEmojiPanelPosition;

  /// on add sticker reaction to a message
  final ValueChanged<int> onSelectSticker;

  /// on close tooltip area
  final VoidCallback onCloseTooltip;

  final TUIChatSeparateViewModel model;

  const TIMUIKitMessageTooltip(
      {Key? key,
      this.toolTipsConfig,
      this.isUseMessageReaction = true,
      required this.model,
      required this.message,
      required this.allowAtUserWhenReply,
      this.onLongPressForOthersHeadPortrait,
      required this.selectEmojiPanelPosition,
      required this.onCloseTooltip,
      required this.onSelectSticker})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => TIMUIKitMessageTooltipState();
}

class TIMUIKitMessageTooltipState extends TIMUIKitState<TIMUIKitMessageTooltip> {
  bool isShowMoreSticker = false;

  /// 消息可撤回检测
  bool isRevocable(int timestamp, int upperTimeLimit) {
    final chatModel = widget.model;
    final message = widget.message;
    final overUpperTimeLimit = (DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < upperTimeLimit;
    final selfMessage = message.isSelf ?? false;
    // 消息超过时间限制，不可撤回
    if (!overUpperTimeLimit) return false;
    // 自己发送的消息，可撤回
    if (selfMessage) return true;

    // 群聊撤回条件判断
    if (chatModel.conversationType == ConvType.group) {
      final groupRole = chatModel.groupInfo?.role;
      // 群主均可撤回消息
      if (groupRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER) return true;
      // 管理员撤回消息
      if (groupRole == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN) {
        // 消息发送者是群主，不可撤回
        if (message.sender == chatModel.groupInfo?.owner) return false;
        // 获取群管理设置，是否允许管理员撤回群员消息
        final Map<String, String>? customInfoMap = chatModel.groupInfo?.customInfo;
        if (customInfoMap?.isEmpty ?? true) return false;
        final adminRevoke = GroupCustomDataModel.fromJson(customInfoMap!).revokeMsgOpt;
        return adminRevoke;
      }
    }

    return false;
  }

  /// 转发权限判断
  bool isForwardable(V2TimMessage message) {
    // 自己消息均可以转发
    if (message.isSelf ?? false) return true;
    final msgType = message.elemType;
    // 群邀请信息不可转发
    if (msgType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
      final customData = message.customElem?.data;
      if (customData != null && customData.isNotEmpty) {
        try {
          final isGroupInvite = jsonDecode(customData)["typeName"] == "groupInvite";
          if (isGroupInvite) return false;
        } catch (_) {}
      }
    }
    // 语音消息仅白名单用户可转发
    if (msgType == MessageElemType.V2TIM_ELEM_TYPE_SOUND) {
      // 是否是白名单用户
      final whiteListAuth = CZMMethodBridge.getInstance().imWhiteListAuth();
      return whiteListAuth;
    }
    return true;
  }

  Widget ItemInkWell({Widget? child, GestureTapCallback? onTap}) {
    return SizedBox(
      width: 40,
      child: InkWell(
        onTap: onTap,
        splashColor: Colors.white,
        child: Container(
          padding: const EdgeInsets.only(bottom: 6, top: 6),
          child: child,
        ),
      ),
    );
  }

  _buildLongPressTipItem(TUITheme theme, TUIChatSeparateViewModel model, double width) {
    // 发送失败
    final sendFail = widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL;
    // 是否是通话消息
    final callingMessage =
        widget.message.customElem?.data != null && MessageUtils.isCallingData(widget.message.customElem!.data!);
    // 消息是否可撤回
    final canRevoke = isRevocable(widget.message.timestamp!, model.chatConfig.upperRecallTime);
    // 消息是否可转发
    final canForward = isForwardable(widget.message);
    // 是否显示撤回按钮
    final shouldShowRevokeAction = !sendFail && canRevoke;
    // 是否显示转发按钮
    final shouldShowForwardAction = !sendFail && canForward;
    // 是否显示回复按钮
    final shouldShowReplyAction = !sendFail && !callingMessage;
    // 是否显示多选按钮
    final shouldShowMultiAction = !sendFail;
    final tooltipsConfig = widget.toolTipsConfig;
    final defaultTipsList = [
      {
        "label": TIM_t("复制"),
        "id": "copyMessage",
        "icon": "images/copy_message.png",
      },
      if (shouldShowForwardAction)
        {
          "label": TIM_t("转发"),
          "id": "forwardMessage",
          "icon": "images/forward_message.png",
        },
      if (shouldShowMultiAction)
        {
          "label": TIM_t("多选"),
          "id": "multiSelect",
          "icon": "images/multi_message.png",
        },
      if (shouldShowReplyAction)
        {
          "label": TIM_t("引用"),
          "id": "replyMessage",
          "icon": "images/reply_message.png",
        },
      {
        "label": TIM_t("删除"),
        "id": "delete",
        "icon": "images/delete_message.png",
      },
      {
        "label": TIM_t("翻译"),
        "id": "translate",
        "icon": "images/translate.png",
      },
      if (shouldShowRevokeAction)
        {
          "label": TIM_t("撤回"),
          "id": "revoke",
          "icon": "images/revoke_message.png",
        }
    ];
    List formattedTipsList = defaultTipsList;
    if (tooltipsConfig != null) {
      formattedTipsList = defaultTipsList.where((element) {
        final type = element["id"];
        if (type == "copyMessage") {
          return tooltipsConfig.showCopyMessage && widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
        }
        if (type == "forwardMessage") {
          return tooltipsConfig.showForwardMessage;
        }
        if (type == "replyMessage") {
          return tooltipsConfig.showReplyMessage;
        }
        if (type == "delete") {
          return (!PlatformUtils().isWeb) && tooltipsConfig.showDeleteMessage;
        }
        if (type == "multiSelect") {
          return tooltipsConfig.showMultipleChoiceMessage;
        }
        if (type == "translate") {
          return tooltipsConfig.showTranslation && widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT;
        }
        if (type == "revoke") {
          return tooltipsConfig.showRecallMessage;
        }
        return true;
      }).toList();
    }
    return formattedTipsList
        .map(
          (item) => SizedBox(
            width: width,
            child: Material(
              color: Colors.white,
              child: ItemInkWell(
                onTap: () {
                  _onTap(item["id"]!, model);
                },
                child: Column(
                  children: [
                    Image.asset(
                      item["icon"]!,
                      package: 'tencent_cloud_chat_uikit',
                      width: 20,
                      height: 20,
                    ),
                    const SizedBox(
                      height: 4,
                    ),
                    Text(
                      item["label"]!,
                      style: TextStyle(
                        decoration: TextDecoration.none,
                        color: theme.darkTextColor,
                        fontSize: 10,
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        )
        .toList();
  }

  _onTap(String operation, TUIChatSeparateViewModel model) async {
    final messageItem = widget.message;
    final msgID = messageItem.msgID as String;
    switch (operation) {
      case "delete":
        widget.onCloseTooltip();
        final confirm = await CZMWidgetBuilderBridge.getInstance().msDialog(
          context,
          desc: "确定删除该条消息吗？",
          content: '删除后将无法恢复，请谨慎操作',
        );
        if (confirm == true) model.deleteMsg(msgID, webMessageInstance: messageItem.messageFromWeb);
        break;
      case "revoke":
        widget.onCloseTooltip();
        final confirm =
            await CZMWidgetBuilderBridge.getInstance().msDialog(context, desc: "是否撤回消息？", content: '撤回后将无法恢复，确定撤回吗？');
        if (confirm == true) model.revokeMsg(messageItem, messageItem.messageFromWeb);
        break;
      case "multiSelect":
        model.updateMultiSelectStatus(true);
        model.addToMultiSelectedMessageList(widget.message);
        break;
      case 'translate':
        model.translateText(widget.message);
        break;
      case "forwardMessage":
        model.addToMultiSelectedMessageList(widget.message);
        CZMWidgetBuilderBridge.getInstance().toForwardMessagePage(ConvType.c2c, false, model);
        break;
      case "copyMessage":
        if (widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) {
          try {
            await Clipboard.setData(ClipboardData(text: widget.message.textElem?.text ?? ""));
            CZMWidgetBuilderBridge.getInstance().showToast("复制成功");
            onTIMCallback(
              TIMCallback(
                type: TIMCallbackType.INFO,
                infoRecommendText: TIM_t("已复制"),
                infoCode: 6660408,
              ),
            );
          } catch (e) {
            print(e);
          }
        }
        break;
      case "replyMessage":
        model.repliedMessage = widget.message;
        if (widget.allowAtUserWhenReply &&
            widget.onLongPressForOthersHeadPortrait != null &&
            !(widget.message.isSelf ?? false)) {
          widget.onLongPressForOthersHeadPortrait!(
            userId: widget.message.sender,
            nameCard: widget.message.nameCard,
            nickName: widget.message.nickName,
          );
        }
        break;
      default:
        onTIMCallback(
          TIMCallback(
            type: TIMCallbackType.INFO,
            infoRecommendText: TIM_t("暂未实现"),
            infoCode: 6660409,
          ),
        );
    }
    widget.onCloseTooltip();
  }

  @override
  Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
    final TUITheme theme = value.theme;

    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: widget.model),
      ],
      builder: (BuildContext context, Widget? w) {
        final TUIChatSeparateViewModel model = Provider.of<TUIChatSeparateViewModel>(context);
        final bool haveExtraTipsConfig =
            widget.toolTipsConfig != null && widget.toolTipsConfig?.additionalItemBuilder != null;
        Widget? extraTipsActionItem = haveExtraTipsConfig
            ? widget.toolTipsConfig!.additionalItemBuilder!(widget.message, widget.onCloseTooltip, null, context)
            : null;
        return Container(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
          child: ConstrainedBox(
            constraints: BoxConstraints(
              maxWidth: min(MediaQuery.of(context).size.width * 0.7, 350),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                if (widget.isUseMessageReaction && widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.up)
                  TIMUIKitMessageReactionEmojiSelectPanel(
                    isShowMoreSticker: isShowMoreSticker,
                    onSelect: (int value) => widget.onSelectSticker(value),
                    onClickShowMore: (bool value) {
                      setState(() {
                        isShowMoreSticker = value;
                      });
                    },
                  ),
                if (widget.isUseMessageReaction &&
                    widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.up &&
                    isShowMoreSticker == false)
                  Container(
                      margin: const EdgeInsets.symmetric(vertical: 6),
                      child: const Divider(
                          thickness: 1,
                          indent: 0,
                          // endIndent: 10,
                          color: Colors.black12)),
                if (isShowMoreSticker == false)
                  Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      if (widget.isUseMessageReaction)
                        Expanded(
                          child: LayoutBuilder(
                            builder: (_, cons) {
                              final width = cons.maxWidth / 5;
                              return Wrap(
                                direction: Axis.horizontal,
                                alignment: WrapAlignment.start,
                                spacing: 0,
                                runSpacing: 8,
                                children: [
                                  ..._buildLongPressTipItem(theme, model, width),
                                  if (extraTipsActionItem != null) extraTipsActionItem
                                ],
                              );
                            },
                          ),
                        ),
                      if (!widget.isUseMessageReaction)
                        LayoutBuilder(builder: (_, cons) {
                          final width = cons.maxWidth / 5;
                          return Wrap(
                            direction: Axis.horizontal,
                            alignment: WrapAlignment.start,
                            spacing: 0,
                            runSpacing: 16,
                            children: [
                              ..._buildLongPressTipItem(theme, model, width),
                              if (extraTipsActionItem != null) extraTipsActionItem
                            ],
                          );
                        })
                    ],
                  ),
                if (widget.isUseMessageReaction &&
                    widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.down &&
                    widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC) ...[
                  Container(
                      margin: const EdgeInsets.symmetric(vertical: 6),
                      child: const Divider(
                          thickness: 1,
                          indent: 0,
                          // endIndent: 10,
                          color: Colors.black12)),
                  TIMUIKitMessageReactionEmojiSelectPanel(
                    isShowMoreSticker: isShowMoreSticker,
                    onSelect: (int value) => widget.onSelectSticker(value),
                    onClickShowMore: (bool value) {
                      setState(() {
                        isShowMoreSticker = value;
                      });
                    },
                  ),
                ]
              ],
            ),
          ),
        );
      },
    );
  }
}
